package com.mazaiting.mockloction

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.*
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import com.mazaiting.common.LOG_DEBUG
import com.mazaiting.common.debug
import java.util.*
import kotlin.concurrent.thread

class MainActivity : AppCompatActivity() {
    // 已经添加测试提供
    private var hasAddTestProvider = false
    private var locationManager: LocationManager? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        LOG_DEBUG = true
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 获取位置管理服务
        locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            if (
                checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ) {
                requestPermissions(
                    arrayOf(
                        Manifest.permission.ACCESS_BACKGROUND_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ), 100
                )
            }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 100) {
            initLocation()
//            updateLocation()
        }
    }

    /**
     * 初始化位置信息
     */
    @SuppressLint("MissingPermission")
    private fun initLocation() {
        //侦听位置发生变化，2000毫秒更新一次，位置超过8米也更新一次
//        locationManager?.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, object :
//        locationManager?.requestLocationUpdates(
//            LocationManager.NETWORK_PROVIDER,
//            1000L,
//            10F,
//            object :
//                LocationListener {
//                override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
//                    debug("onStatusChanged")
//                }
//
//                @SuppressLint("MissingPermission")
//                override fun onProviderEnabled(provider: String) {
//                    debug("onProviderEnabled")
//                    val lastKnownLocation = locationManager?.getLastKnownLocation(provider)
//                    upData(lastKnownLocation)
//                }
//
//                override fun onProviderDisabled(provider: String) {
//                    debug("onProviderDisabled")
//                }
//
//                override fun onLocationChanged(location: Location) {
//                    // 当GPS定位信息发生改变时，更新位置
//                    debug("onLocationChanged")
//                    upData(location)
//                }
//            })
        locationManager?.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            1000L,
            10F,
            object :
                LocationListener {
                override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
                    debug("onStatusChanged")
                }

                @SuppressLint("MissingPermission")
                override fun onProviderEnabled(provider: String) {
                    debug("onProviderEnabled")
                    val lastKnownLocation = locationManager?.getLastKnownLocation(provider)
                    upData(lastKnownLocation)
                }

                override fun onProviderDisabled(provider: String) {
                    debug("onProviderDisabled")
                }

                override fun onLocationChanged(location: Location) {
                    // 当GPS定位信息发生改变时，更新位置
                    debug("onLocationChanged")
                    upData(location)
                }
            })
        // 判断是否开启允许模拟位置
        // Android 6.0以下，通过Setting.Secure.ALLOW_MOCK_LOCATION判断
        // Android 6.0及以上，需要【选择模拟位置信息应用】，未找到方法，因此通过addTestProvider是否可用判断
        var canMockPosition =
            (Settings.Secure.getInt(contentResolver, Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0)
                    || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M

        if (canMockPosition && !hasAddTestProvider) {
            try {
                // gps 提供
                val providerStr = LocationManager.GPS_PROVIDER
                // 位置提供者
                val provider = locationManager?.getProvider(providerStr)
                if (null != provider) {
                    // 添加测试位置提供
                    locationManager?.addTestProvider(
                        provider.name,
                        provider.requiresNetwork(),
                        provider.requiresSatellite(),
                        provider.requiresCell(),
                        provider.hasMonetaryCost(),
                        provider.supportsAltitude(),
                        provider.supportsSpeed(),
                        provider.supportsBearing(),
                        provider.powerRequirement,
                        provider.accuracy
                    )
                } else {
                    locationManager?.addTestProvider(
                        providerStr, true, true, false,
                        false, true, true, true, Criteria.POWER_HIGH,
                        Criteria.ACCURACY_FINE
                    )
//        if (providerStr.equals(LocationManager.GPS_PROVIDER)) {
//          locationManager.addTestProvider(
//            providerStr
//            , true, true, false, false, true, true, true
//            , Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
//        } else if (providerStr.equals(LocationManager.NETWORK_PROVIDER)) {
//          locationManager.addTestProvider(
//            providerStr
//            , true, false, true, false, false, false, false
//            , Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
//        } else {
//          locationManager.addTestProvider(
//            providerStr
//            , false, false, false, false, true, true, true
//            , Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
//        }
                }
                // 设置测试提供可用
                locationManager?.setTestProviderEnabled(providerStr, true)
                // 设置测试提供状态
                locationManager?.setTestProviderStatus(
                    providerStr,
                    LocationProvider.AVAILABLE,
                    null,
                    System.currentTimeMillis()
                )
                // 模拟位置可用
                hasAddTestProvider = true
                canMockPosition = true
            } catch (e: Exception) {
                canMockPosition = false
            }
        } else {
            debug("未开启模拟位置")
        }
    }

    private fun upData(location: Location?) {
        if (location != null) {
            val sb = StringBuilder()
            sb.append("实时的位置信息:\n")
            sb.append("经度:")
            sb.append(location.longitude)
            sb.append("\n纬度:")
            sb.append(location.latitude)
            sb.append("\n高度:")
            sb.append(location.altitude)
            sb.append("\n速度：")
            sb.append(location.speed)
            sb.append("\n方向：")
            sb.append(location.bearing)
            sb.append("\n当地时间：")
            sb.append(location.time)

            val geocoder = Geocoder(this)
            val address = geocoder.getFromLocation(location.latitude, location.longitude, 1)[0]
            sb.append("\n国家: ")
            sb.append(address.countryName)
            sb.append("\n城市: ")
            sb.append(address.locality)
            var i = 0
            val addressLine: String? = address.getAddressLine(i)
            while (addressLine.isNullOrEmpty()) {
                sb.append("\n街道$i:")
                sb.append(addressLine)
                i++
            }
            debug(sb.toString())

            updateLocation(location)
        }
    }

    /**
     * 更新位置
     */
    private fun updateLocation(location: Location) {
        thread {
            while (true) {
                Thread.sleep(1000)

                if (hasAddTestProvider) {
                    val providerStr = LocationManager.GPS_PROVIDER
                    val mockLocation = Location(providerStr)
//                    mockLocation.latitude = location.latitude + 0.002715f// 维度（度）
//                    mockLocation.longitude = location.longitude - 0.0051f // 经度（度）
                    mockLocation.latitude = 43.870168
                    mockLocation.longitude = 87.562230
                    mockLocation.altitude = location.altitude // 高程（米）
                    mockLocation.bearing = location.bearing // 方向（度）
                    mockLocation.speed = location.speed //速度（米/秒）
                    mockLocation.accuracy = location.accuracy // 精度（米）
                    mockLocation.time = Date().time // 本地时间
                    mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
                    locationManager?.setTestProviderLocation(providerStr, mockLocation)
                } else {
                    debug("hasAddTestProvider: $hasAddTestProvider")
                }
            }
        }
    }
}
